﻿using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SimpleWebApp.Demo02.MVC.DTO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace SimpleWebApp.Demo02
{
    public class Run
    {
        public static void v1()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder =>
                {
                    builder.Configure(app =>
                    {
                        app.Run(context => context.Response.WriteAsync("Hello v1 World"));
                    });
                })
                .Build()
                .Run();
        }

        public static void v2()
        {
            static RequestDelegate Middleware1(RequestDelegate next)
                => async context =>
                {
                    await context.Response.WriteAsync("Hello");
                    await next(context);
                };

            static RequestDelegate Middleware2(RequestDelegate next)
                      => async context =>
                      {
                          await context.Response.WriteAsync(" v2 World!");
                      };

            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder =>
                {
                    builder.Configure(app =>
                    {
                        app.Use(Middleware1);
                        app.Use(Middleware2);
                    });
                })
                .Build()
                .Run();
        }

        public static void v3()
        {
            Host.CreateDefaultBuilder()
                .ConfigureServices(svcs =>
                {
                    // 首先注册这个服务
                    svcs.AddSingleton(new StringContentMiddleware("Hello v3 World!"));
                })
                .ConfigureWebHostDefaults(builder =>
                {
                    builder.Configure(app =>
                    {
                        // 然后使用这个中间件
                        app.UseMiddleware<StringContentMiddleware>();
                    });
                })
                .Build()
                .Run();
        }

        public static void v4()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder =>
                {
                    builder.Configure(app =>
                    {
                        // 然后使用这个中间件
                        app.UseMiddleware<StringContentMiddlewareV2>("Hello");
                        app.UseMiddleware<StringContentMiddlewareV2>(" v4 World!", false);
                    });
                })
                .Build()
                .Run();

        }

        public static void v5()
        {
            Host.CreateDefaultBuilder()
              .ConfigureWebHostDefaults(builder =>
              {
                  // 使用自定义的 Startup
                  // 检查整个默认类型的加载信息
                  builder.UseStartup<Startup>();
              })
              .Build()
              .Run();
        }

        public static void v6()
        {
            // 这是一个 MVC 示例

            Host.CreateDefaultBuilder()
              .ConfigureWebHostDefaults(builder =>
              {
                  builder.ConfigureServices(svcs =>
                  {
                      svcs.AddSingleton<IFoo, Foo>();
                      svcs.AddSingleton<IBar, Bar>();
                      svcs.AddControllersWithViews();

                      svcs.Configure<RazorViewEngineOptions>(option =>
                      {
                          //o.ViewLocationFormats.Clear();
                          // 注意，这里的格式化参数
                          // {1} = Controller
                          // {0} = Action
                          option.ViewLocationFormats.Add("/Demo02/MVC/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
                      });

                  });

                  builder.Configure(app =>
                  {
                      app.UseRouting();
                      app.UseEndpoints(endpoints => endpoints.MapControllers());
                  });


                  builder.UseSetting(WebHostDefaults.ContentRootKey, Path.Combine(Directory.GetCurrentDirectory(), "Demo02/MVC"));
              })
              .Build()
              .Run();
        }

        public static void v7()
        {
            Environment.SetEnvironmentVariable("ASPNETCORE_FOOBAR:FOO", "Foo");
            Environment.SetEnvironmentVariable("ASPNETCORE_FOOBAR:BAR", "Bar");
            Environment.SetEnvironmentVariable("ASPNETCORE_BAZ", "Baz");

            // 通过静态类型 Host 的 CreateDefaultBuilder 方法创建的 HostBuilder 默认选择的是前缀为“DOTNET_”的环境变量
            IHostBuilder hostBuilder = Host.CreateDefaultBuilder();

            // builder 是 WebHostBuilder
            // 它只会选择名称以“ASPNETCORE_”为前缀的环境变量
            hostBuilder.ConfigureWebHostDefaults(builder =>
            {
                builder.UseStartup<StartupV2>();
            }).Build().Run();
        }

        public static void v8()
        {
            Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder =>
            {
                // 通过显示指定配置
                builder.UseSetting("FOOBAR:FOO", "Foo");
                builder.UseSetting("FOOBAR:Bar", "Bar");
                builder.UseSetting("BAZ", "Baz");

                // ASP.NET Core 应用的服务器默认使用 launchSettings.json 文件定义的监听地址
                // 但是我们可以通过修改配置采用其他的监听地址。包括端口在内的监听地址是通过名称为 urls 的配置项来控制的

                // 如果记不住这个配置项的名称，也可以直接使用定义在 WebHostDefaults 中对应的只读属性 ServerUrlsKey
                // 该静态类型中还提供了其他一些预定义的配置项名称，所以这也是一个比较重要的类型
                builder.UseSetting("urls", "http://0.0.0.0:8888;http://0.0.0.0:9999");
                // 与上面是等价的
                builder.UseUrls("http://0.0.0.0:8881", "http://0.0.0.0:9991");

                builder.UseStartup<StartupV2>();
            }).Build().Run();
        }

        public static void v9()
        {
            var configuration = new ConfigurationBuilder()
                .AddInMemoryCollection(new Dictionary<string, string>
                {
                    ["Foobar:Foo"] = "Foo",
                    ["Foobar:Bar"] = "Bar",
                    ["Baz"] = "Baz",
                }).Build();

            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder =>
                   {
                       // 使用指定的 Configuration 进行配置合并
                       builder.UseConfiguration(configuration);
                       builder.UseStartup<StartupV2>();
                   })
                .Build()
                .Run();
        }

        public static void v10()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder =>
                {
                    builder.ConfigureAppConfiguration(config =>
                    {
                        // 与 v9 一样
                        // 在 ConfigureAppConfiguration 进行配置
                        config.AddInMemoryCollection(new Dictionary<string, string>
                        {
                            ["Foobar:Foo"] = "Foo",
                            ["Foobar:Bar"] = "Bar",
                            ["Baz"] = "Baz",
                        });
                    });
                    builder.UseStartup<StartupV2>();
                })
                .Build()
                .Run();
        }


        public static void v11()
        {
            Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(builder =>
                {
                    builder.ConfigureServices(svcs =>
                    {
                        svcs.AddSingleton<IStartupFilter, FooStartupFilter>();
                    });

                    builder.Configure(app =>
                    {
                        app.UseMiddleware<BarMiddleware>();
                        app.Run(handler =>
                        {
                            return handler.Response.WriteAsync("...=>");
                        });
                    });

                })
                .Build()
                .Run();
        }
    }
}
